package com.shootingGame
{
	import Nonoba.api.Connection;
	import Nonoba.api.Message;
	import Nonoba.api.MessageEvent;
	
	import com.common.KeyStates;
	import com.common.screens.PlayScreen;
	import com.common.utils.Math2;
	import com.common.utils.TransformEZ;
	import com.shootingGame.weaponsClasses.Weapon;
	
	import flash.events.TimerEvent;
	
	public class MultiplayerGamePlayManager extends GamePlayManager
	{

		public static const MSG_MY_USER_DATA : String = "my_user_data";
		public static const MSG_PLAYERS_IN_GAME : String = "players_in_game";
		public static const MSG_JOIN_GAME : String = "join_Game";
		public static const MSG_MOUSE_COORDS : String = "mouse_coords";
		public static const MSG_PLAYER_POSITION : String = "player_position";
		public static const MSG_KEYSTATES : String = "keystates";
		public static const MSG_THRUST : String = "thrust";
		public const MSG_PICKED_UP_WEAPON : String = "pickup_weapon";
        public const MSG_SPAWN_WEAPON : String = "spawn_weapon";
        public const MSG_WEAPON_LOCATIONS : String = "weapon_locations";
        public const MSG_EXPIRED_PLAYER : String = "expired_player";
        public const MSG_RESPAWN : String = "respawn";

        public static const MSG_ORDINANCE_DATA : String = "ordinance_data";
        public static const MSG_PLAYER_DATA : String = "player_data";
        public static const MSG_PICKUP_DATA : String = "pickup_data";        
		
		public static const MSG_SEND_DELAY_GENERAL : int = 20;
		public static const MSG_SEND_DELAY_PLAYER_POSITION : int = 100;
		
		public var primaryUserName : String;
		public var connection : Connection;
		protected var sendDelay_General_Counter : int;
		protected var sendDelay_PlayerPosition_Counter : int;
		
		
		public function MultiplayerGamePlayManager(playScreen:PlayScreen, connection:Connection)
		{
			super(playScreen, false);
			this.connection = connection;
			connection.addEventListener(MessageEvent.MESSAGE, onMessage);
			sendDelay_General_Counter = 0;
			sendDelay_PlayerPosition_Counter = 0;
			initializeGame();
		}
		
		override public function onUpdate(evt:TimerEvent) : void{
			super.onUpdate(evt);
			incrementSendDelayCounters();
			if(sendDelay_General_Counter >= MSG_SEND_DELAY_GENERAL){
				sendDelay_General_Counter = 0;
				sendMessages_General();
			}
			if(sendDelay_PlayerPosition_Counter >= MSG_SEND_DELAY_PLAYER_POSITION){
				sendDelay_PlayerPosition_Counter = 0;
				sendMessages_PlayerPosition();
			}
			
		}
		
		override protected function initializeGame():void{
//			NonobaAPI.GetUsername(playScreen.stage, receivedUserName);
			connection.Send(MSG_MY_USER_DATA, player1.width, player1.height);
		}
		
		protected function incrementSendDelayCounters() : void {
			sendDelay_General_Counter++;
			sendDelay_PlayerPosition_Counter++;
		}
		
		virtual protected function makeSpectator(player):void{
			player.visible = false;
			player.canRegisterOrdinanceImpact = false;
		}
		
		virtual protected function spawn(player:Player):void{
			player.spawn();
		}
		
		virtual protected function onMessage(e:Object){
			var message:Object = e.message;
			var tmpPlayer:Player;
			var tmpWeapon:Weapon;
			var attachmentsStr:String;
			var charPosition:int;
			var char1:String;
			var char2:String;
			var i : int;
			var n : int; 
			var j : int;
			var m : int;
			switch(message.Type){
				case MSG_MY_USER_DATA:{
					
					player1.id = message.GetInt(0);
					player1.userName = message.GetString(1);
					player1.memoryX = message.GetNumber(2);
					player1.memoryY = message.GetNumber(3);
					spawn(player1);
					break;
				}
				case MSG_PLAYERS_IN_GAME:{
					
					n = message.length;
					for(i = 0; i < n; i+=2) {
						tmpPlayer = new Player(false, new DummyPlayer());
						tmpPlayer.id = message.GetInt(i);
						tmpPlayer.userName = message.GetString(i+1);
						TransformEZ.setColor(tmpPlayer.model.body, Math2.rand(uint.MAX_VALUE) as uint);
						TransformEZ.setColor(tmpPlayer.model.face, Math2.rand(uint.MAX_VALUE) as uint);
						playerHolder.addChild(tmpPlayer);
						spawn(tmpPlayer);
					}
					break;
				}
				case MSG_JOIN_GAME:{
					if(message.GetInt(0) != player1.id){
						tmpPlayer = new Player(false, new DummyPlayer(), null, message.GetInt(2), message.GetInt(3));
						tmpPlayer.id = message.GetInt(0);
						tmpPlayer.userName = message.GetString(1);
						TransformEZ.setColor(tmpPlayer.model.body, 0x663300);
						TransformEZ.setColor(tmpPlayer.model.face, 0x999900);
						playerHolder.addChild(tmpPlayer);
						spawn(tmpPlayer);
					}
					break
				}
				case MSG_KEYSTATES:{
					if(message.GetInt(0) != player1.id){
						n = playerList.length;
						for(i = 0; i < n; i++) {
							tmpPlayer = playerList[i];
							if(tmpPlayer != player1 && tmpPlayer.id == message.GetInt(0)){
								tmpPlayer.keyStates.UP = message.GetBoolean(2);
								tmpPlayer.keyStates.DOWN = message.GetBoolean(3);
								tmpPlayer.keyStates.LEFT = message.GetBoolean(4);
								tmpPlayer.keyStates.RIGHT = message.GetBoolean(5);
								tmpPlayer.keyStates.MOUSELEFT_DOWN = message.GetBoolean(6);
								tmpPlayer.keyStates.MOUSE_X = message.GetNumber(7);
								tmpPlayer.keyStates.MOUSE_Y = message.GetNumber(8);
								break;
							}
						}						
					}
					break;
				}
				case MSG_THRUST:{
					n = playerList.length;
					for(i = 0; i < n; i++) {
						tmpPlayer = playerList[i];
						if(tmpPlayer != player1 && tmpPlayer.id == message.GetInt(0)){
							tmpPlayer.memoryX = message.GetInt(2);
							tmpPlayer.memoryY = message.GetInt(3);
							tmpPlayer.thrustX = message.GetInt(4);
							tmpPlayer.thrustY = message.GetInt(5);
							tmpPlayer.facing = message.GetInt(6);
							break;
						}
					}
					break;
				}
				case MSG_EXPIRED_PLAYER:{
					trace(MSG_EXPIRED_PLAYER, message.GetInt(0));
					n = playerList.length;
					for(i = 0; i < n; i++) {
						tmpPlayer = playerList[i];
						if(tmpPlayer.id == message.GetInt(0)){
							kill(tmpPlayer);
							break;
						}
					}
					break;
				}
				case MSG_RESPAWN:{
					n = playerList.length;
					for(i = 0; i < n; i++) {
						tmpPlayer = playerList[i];
						if(tmpPlayer.id == message.GetInt(0)){
							tmpPlayer.memoryX = message.GetNumber(1);
							tmpPlayer.memoryY = message.GetNumber(2);
							if(tmpPlayer.id == player1.id){
								player1.x = tmpPlayer.memoryX;
								player1.y = tmpPlayer.memoryY;
							}
							spawn(tmpPlayer);
							break;
						}
					}
					break;
				}
				case MSG_PLAYER_DATA:{
					i = 0;
					n = message.length;
					m = playerList.length;
					for(i = 0; i < n; i+=4){
						for(j = 0; j < m; j++) {
							tmpPlayer = playerList[j];
							if(tmpPlayer.id == message.GetInt(i)){
								if(tmpPlayer.id != player1.id){
									tmpPlayer.memoryX = message.GetNumber(i+1);
									tmpPlayer.memoryY = message.GetNumber(i+2);
								}
								if(tmpPlayer.id != player1.id){
									attachmentsStr = message.GetString(i+3);
									charPosition = attachmentsStr.search("weapon:");
									charPosition += 7;
									char1 = attachmentsStr.charAt(charPosition);
									if(int(char1) == 0){
										if(tmpPlayer.weapon != null)
											tmpPlayer.weapon = null;
									}
									else
										if(tmpPlayer.weapon){
											if(tmpPlayer.weapon.type != int(char1))
												createWeapon(int(char1)).attachedTo = tmpPlayer;
										}
										else
											createWeapon(int(char1)).attachedTo = tmpPlayer;
								}
								break;
							}
						}
					}
					break;
				}				
				default:{
					trace("Got unhandled message > " + message)
				}
			}
		}
		
		virtual protected function sendMessages_General() : void {
			var keyStates:KeyStates;
			var keyStatesMessage:Message;
			var mouseCoordsMessage:Message;
			keyStates = player1.keyStates;
			keyStatesMessage = new Message(MSG_KEYSTATES, keyStates.UP, keyStates.DOWN, keyStates.LEFT, keyStates.RIGHT, keyStates.MOUSELEFT_DOWN, mouseX, mouseY);
			connection.Send(keyStatesMessage);
		}
		
		virtual protected function sendMessages_PlayerPosition() : void {
			connection.Send(new Message(MSG_PLAYER_POSITION, player1.memoryX, player1.memoryY));
		}
		
		virtual protected function createWeapon(type:int): Weapon{
			return null;
		}
		
		override protected function kill(p:Player):void{
			trace("dieing", p.id);
			p.hitPoints = 0;
		}
	}
}